package com.ocom.nettyxf.ropo;


import com.ocom.common.utils.CommonUtil;
import com.ocom.common.utils.NumConvertUtil;
import com.ocom.nettyxf.util.CRC16;
import com.ocom.nettyxf.util.DES;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;

/**
 * 门禁tcp通信
 */

@Slf4j
@Data
@NoArgsConstructor
@AllArgsConstructor
public class TcpServiceRopo {
    //包头STX 2字节  ca ac
    String stx="caac";

    //数据长度 2个字节
    String strLength ="0000";

    //版本 1个字节
    String edition="00";

    //类型 1个字节
    String type="00";

    //终端地址 4个字节
    String machId="00000000";

    //请求应答标识 1个字节
    //0x01：请求
    //0x02：应答
    String respTip="02";

    //包号  4个字节
    String packageNum="00000000";

    //SessionID  4个字节
    String sessionId="00000000";


    /**
     * 数据域
     */
    //命令类型  2个字节
    String  commandType="0000";

    //命令类型  2个字节
    String  commandLength="0000";


    //命令参数  不定长 默认1
    String  commandParam="00";

    //加密校验 8个字节
    String sign="0000000000000000";


    String orgStr = "";


    //包尾ETX   2个字节
    String ext="acca";



    public void setCommandParam(String commandParam,Integer len, String msg) {
        if (commandParam.length() < len) {
            int length = commandParam.length();
            for (int i = length; i < len; i++) {
                commandParam = "0"+commandParam  ;
            }
        }
        if (commandParam.length() > len) {
            commandParam= commandParam.substring(0,len);
        }
        String gbkMsg = "";
        if (!CommonUtil.isNull(msg)) {
            gbkMsg = NumConvertUtil.toGBK(msg);
        }
        String lenStr = NumConvertUtil.IntToHexStringNum(gbkMsg.length() / 2, 2);
        this.commandParam = commandParam + lenStr + gbkMsg;
    }

//    public void setCommandParam(String commandParam,Integer len) {
//        if (commandParam.length() < len) {
//            int length = commandParam.length();
//            for (int i = length; i < len; i++) {
//                commandParam = "0"+commandParam  ;
//            }
//        }
//        if (commandParam.length() > len) {
//            commandParam= commandParam.substring(0,len);
//        }
//        this.commandParam = commandParam;
//    }

    //命令参数长度为0的时候 tcp长最小33个字节
    public  TcpServiceRopo(byte[] bytes)  {

        String messageData=NumConvertUtil.bytesToHexString(bytes);

        this.orgStr= messageData;

        //开头
        this.stx=NumConvertUtil.byteToHex(bytes[0],bytes[1]);

        //结尾
        this.ext=NumConvertUtil.byteToHex(bytes[bytes.length-2],bytes[bytes.length-1]);

        //长度
        this.strLength=NumConvertUtil.byteToHex(bytes[2],bytes[3]);

        this.edition=NumConvertUtil.byteToHex(bytes[4]);

        this.type=NumConvertUtil.byteToHex(bytes[5]);

        this.machId=NumConvertUtil.byteToHex(bytes[6],bytes[7],bytes[8],bytes[9]);

        this.respTip=NumConvertUtil.byteToHex(bytes[10]);

        this.packageNum=NumConvertUtil.byteToHex(bytes[11],bytes[12],bytes[13],bytes[14]);

        this.sessionId=NumConvertUtil.byteToHex(bytes[15],bytes[16],bytes[17],bytes[18]);

        this.commandType=NumConvertUtil.byteToHex(bytes[19],bytes[20]);

        this.commandLength=NumConvertUtil.byteToHex(bytes[21],bytes[22]);

        byte[] paramBytes=new byte[Integer.parseInt(this.commandLength,16)];
        for(int i=23;i<=bytes.length-11;i++){
            paramBytes[i-23]=bytes[i];
        }

        this.commandParam=NumConvertUtil.byteToHex(paramBytes);

        byte[] signBytes=new byte[8];
        for(int i=bytes.length-10;i<bytes.length-2;i++){
            signBytes[i-(bytes.length-10)]=bytes[i];
        }

        this.sign=NumConvertUtil.byteToHex(signBytes);
    }


    public String getHexStr() throws Exception {
        try {
            if(CommonUtil.isNull(this.commandParam)){
                this.commandParam = "0001";
            }

            byte[] params=NumConvertUtil.hexStringToByte(this.commandParam);
            //整体长度  strLength 修改 10转16
            String len2=Integer.toHexString(params.length);
            this.commandLength="0000";
            StringBuilder stringBuilder2=new StringBuilder(this.strLength);
            stringBuilder2.replace(this.commandLength.length()-len2.length(),this.commandLength.length(),len2);
            this.commandLength=stringBuilder2.toString();


            //整体长度  strLength 修改 10转16
            String len=Integer.toHexString(params.length+27);
            this.strLength="0000";
            StringBuilder stringBuilder=new StringBuilder(this.strLength);
            stringBuilder.replace(this.strLength.length()-len.length(),this.strLength.length(),len);
            this.strLength=stringBuilder.toString();

            //校验数据:
            String yanqian=this.edition+this.type+this.machId+this.respTip+this.packageNum+this.sessionId+this.commandType+this.commandLength+this.commandParam;

            //crc16
            int crc= CRC16.calcCrc16(NumConvertUtil.hexStringToByte(yanqian));
            String crcHexStr=NumConvertUtil.reverseHex(NumConvertUtil.IntToHexStringNum(crc,4));

            //异或和
            String yhh=NumConvertUtil.hexYihuo(yanqian);
            if(yhh.length()==1){
                yhh="0"+yhh;
            }

            //累加和
            String ljh=NumConvertUtil.hexLeijia(yanqian);
            if(ljh.length()==1){
                ljh="0"+ljh;
            }

            //包号
            String packageNum=this.getPackageNum();

            //验签
            String signData=packageNum+crcHexStr+yhh+ljh;

            //des加密
            DES des = new DES(NumConvertUtil.hexStringToByte("0044C3D1237CA268"));
            byte[] bytes1 = des.encrypt(NumConvertUtil.hexStringToByte(signData));
            this.sign=NumConvertUtil.bytesToHexString(bytes1).substring(0, 16);

            return this.stx+this.strLength+yanqian+this.sign+this.ext;
        }catch (Exception exception){
            log.info("【切面异常】 【{}】【{}】",this,exception);
            return "";
        }

    }


}
